<?php

namespace App\Http\Controllers\Weixin;

use App\Common\Curl;
use App\Common\Http;
use App\Models\V1\ChangeOrderTemplateModel;
use App\Models\V1\NewOrderTemplateModel;
use App\Models\V1\OrderProcessTemplateModel;
use EasyWeChat\Foundation\Application;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Controllers\www\Zhongchou666Controller;
use EasyWeChat\Payment\Order;
use App\Models\Common\UserRegisterTemplateModel;


class WeixinServiceController extends Controller
{

    public $wxApp;
    private $sendTemplate = true;
    public function __construct()
    {
        $config = $this->get_base_config();
        $this->wxApp = new Application($config);
    }


    private function get_base_config()
    {
        $isWindow = is_windows();
        if ($isWindow) {
            
            $file = public_path('easywechat.log');
            
        } else {
            $file = dirname(app_path(''))."/easywechat.log";
        }
        $config = [
            'debug' => true,
            'app_id' => env('WX_APP_ID'),
            'secret' => env('WX_SECRET'),
            'token' => env('WX_TOKEN'),
            'aes_key' => env('WX_AES_KEY'), // 可选
            'payment' => [
                'merchant_id'        => env('WX_MERCHANT_ID'),
                'key'                => env('WX_PAYKEY'),
                'cert_path'          => dirname(app_path('')).'/zhengshu/wxpay/apiclient_cert.pem', // XXX: 绝对路径！！！！
                'key_path'           => dirname(app_path('')).'/zhengshu/wxpay/apiclient_key.pem',      // XXX: 绝对路径！！！！
                'notify_url'         => '默认的订单回调地址',       // 你也可以在下单时单独设置来想覆盖它
            ],
            'log' => [
                'level' => 'debug',
                'permission' => 0777,
                'file' => $file, // XXX: 绝对路径！！！！
            ],
        ];
        return $config;
    }


    /*
     * 网页授权登录配置
     * */
    private function oauth_config($callbackUrl)
    {
        $config = $this->get_base_config();
        $config['oauth'] = [
            'scopes' => ['snsapi_userinfo'],
            'callback' => $callbackUrl,
        ];
        return $config;
    }

    /*
     * 不用获取详细信息的配置
     * */
    private function oauth_config_base($callbackUrl)
    {

        $config = $this->get_base_config();
        $config['oauth'] = [
            'scopes' => ['snsapi_base'],
            'callback' => $callbackUrl,
        ];
        return $config;
    }

    /*
     * 网页授权APP实例化
     * */
    private function get_oauth_weixin_app($callbackUrl)
    {
        $config = $this->oauth_config($callbackUrl);
        return new Application($config);
    }

    /*
     * 获得仅仅获取OpenID的网页授权
     * */
    private function get_oauth_weixin_app_base($callbackUrl)
    {
        $config = $this->oauth_config_base($callbackUrl);
        return new Application($config);
    }

    /**
     * 移动APP的配置
     * */
    public function get_oauth_client_app()
    {
        $config = $this->get_base_config();
        $config['app_id']                   = env('OPEN_APP_ID');
        $config['payment']['merchant_id']   = env('OPEN_WX_MERCHANT_ID');
        return new Application($config);
    }


    /*
     * 获得微信APP实例
     * @param type 0:不需要授权 1:仅仅获得openID 2:获得用户信息 3.移动客户端app实例
     * */
    public function get_weixin_app($type = 0, $callbackUrl = '')
    {
        switch ($type) {
            case 0:
                $app = $this->wxApp;
                break;
            case 1:
                $app = $this->get_oauth_weixin_app_base($callbackUrl);
                break;
            case 2:
                $app = $this->get_oauth_weixin_app($callbackUrl);
                break;
        }
        $this->wxApp = $app;
        return $app;
    }


    /*
     * 创建微信菜单
     *
     * */
    public function create_menu()
    {
        $menu = $this->wxApp->menu;
        $host = env('ADMIN_HOST');
        $buttons = [
            [
                "type" => "view",
                "name" => "clo系统",
                "url" => $host."/clo/system/wxlogin"
            ],

            /*[
                "name"       => "菜单",
                "sub_button" => [
                    [
                        "type" => "view",
                        "name" => "搜索",
                        "url"  => "http://www.soso.com/"
                    ],
                    [
                        "type" => "view",
                        "name" => "视频",
                        "url"  => "http://v.qq.com/"
                    ],
                    [
                        "type" => "click",
                        "name" => "赞一下我们",
                        "key" => "V1001_GOOD"
                    ],
                ],
            ],*/
        ];
        $menu->add($buttons);
    }


    /*
     * 微信认证入口
     * */
    public function service(Request $request)
    {

        $response = $this->wxApp->server->serve();
        return $response;



        $GLOBALS['wxservice']   = $this;
        $response = $this->wxApp->server->setMessageHandler(function($message){


            switch ($message->MsgType) {
                case 'event':

                    $event  = $message->Event;
                    switch($event){

                        case 'subscribe':
                                $key    = $message->EventKey ? $message->EventKey : '';
                                $key    = substr($key,8);
                                debug_log('eventkey',$key);
                                //666的订单
                                if(preg_match('/^10000\d*/',$key)){

                                    $orderId            = $key%1000000;
                                    $zhongchouCroller   = new Zhongchou666Controller();
                                    $zhongchouCroller->send_first_order($orderId);
                                }
                                return '欢迎关注';
                            break;
                    }
                    $content = object_to_array($message);
                    debug_log('guanzhu',$content);
                    return '收到消息';
                    break;
                case 'text':
                    return '收到文字消息';
                    break;
                case 'image':
                    return '收到图片消息';
                    break;
                case 'voice':
                    return '收到语音消息';
                    break;
                case 'video':
                    return '收到视频消息';
                    break;
                case 'location':

                    $data   = new OrderProcessTemplateModel();
                    $data->openId = $message->FromUserName;
                    $data->orderInfo = 'xx给你筹集了3元';
                    $data->orderSn  = time();
                    $data->orderStatus = "众筹中";
                    $data->otherInfo = "查看进度";
                    $data->orderTime    = date_time();
                    $data->orderType    = "薪酬单";
                    $data->url      = "http://www.baidu.com";
                    $GLOBALS['wxservice']->send_order_process_template($data);
                    return '收到坐标消息';
                    break;
                case 'link':
                    return '收到链接消息';
                    break;
                // ... 其它消息
                default:
                    return '收到其它消息';
                    break;
            }
        });

        return $response->serve();

    }

    private const TARGET_URL_KEY = 'target_url';
    public function userinfo(Request $request)
    {
        // 未登录
        $wechatUser     = $request->session()->get('wechat_user');
        if($wechatUser){
            return $wechatUser;
        }

        $targetUrl      = $request->getRequestUri();
        $targetUrl      = str_replace('/', '-', base64_encode($targetUrl));
        $callbackUrl    = url("weixin/weixinService/oauth_callback/".$targetUrl);

        $oauth          = $this->get_weixin_app(2, $callbackUrl)->oauth;
        $oauth->state   = base64_encode($targetUrl);

        // 这里不一定是return，如果你的框架action不是返回内容的话你就得使用
        $oauth->redirect()->send();
        exit();
        // return $oauth->redirect();
    }

    public function oauth_callback(Request $request, $url)
    {
        $targetUrl = base64_decode(str_replace('-', '/', $url));

        $oauth = $this->wxApp->oauth;
        $user = $oauth->user();

        $request->session()->put('wechat_user',$user->toArray());
        $request->session()->save();

        return response()->redirectTo($targetUrl);
    }

    /*
     * 获取微信openID
     * */
    public function get_openId()
    {
        return  $this->wxApp->access_token->getToken();
    }


    public function isSubscribe($openId,$token = ''){
        $token  = $token ? $token : $this->wxApp->access_token->getToken();
        $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$token}&openid={$openId}&lang=zh_CN";
        
        $http = new Http();
        $info = $info = $http->send($url);
        debug_log('关注信息',$info);
        $info = \GuzzleHttp\json_decode($info);
        $subscribe = $info->subscribe;
        if($subscribe == 1){
            return true;
        }else{
            return false;
        }

    }


    /**
     * 发送分会订单模板
     * @param ChapterOrderTemplate $data 模板信息
     * */
    public function send_chapter_order_template(NewOrderTemplateModel $data){

        if($this->sendTemplate == false) return;
        $templateId = "-R5gMrOPB9_YHnedEJOmR5ZNVMa7bUJFB_mCloolU8s";
        $info       = [
            "first"     => $data->orderName,
            "keyword1"  => $data->orderSn,
            "keyword2"  => $data->orderInfo,
            "keyword3"  => $data->orderTime,
            "remark"    => $data->otherInfo
        ];

        $notice = $this->wxApp->notice;
        $notice->to($data->openId)
            ->uses($templateId);
        if($data->url){
            $notice->andUrl($data->url);
        }
        return $notice->data($info)->send();
    }



    /**
     * 订单更新通知
     * 发送订单变更通知
     *
     * */
    public function send_chapter_order_change_template(ChangeOrderTemplateModel $data){
        if($this->sendTemplate == false) return;
        $templateId = "hUtBFwlSAQqTY_i0wcQDXWIAphaPrslFUQx-2ISQsLQ";
        $info       = [
            "first"     => $data->title,
            "keyword1"  => $data->orderSn,
            "keyword2"  => $data->orderInfo,
            "keyword3"  => $data->changeInfo,
            "remark"    => $data->otherInfo
        ];


        $notice = $this->wxApp->notice;
        $notice->to($data->openId)
            ->uses($templateId);
        if($data->url){
            $notice->andUrl($data->url);
        }
        return $notice->data($info)->send();
    }

    /**
     * 发送订单进度通知
     * @param OrderProcessTemplateModel $template 订单数据
     * */
    public function send_order_process_template(OrderProcessTemplateModel $data){


        if($this->sendTemplate == false) return;
        $templateId = "l8QLFBvODIMSc-u618Hmq8KxKsg3gHO4FGYVhO79mJ8";
        $info       = [
            "first"     => $data->orderInfo,
            "keyword1"  => $data->orderSn,
            "keyword2"  => $data->orderType,
            "keyword3"  => $data->orderTime,
            "keyword4"  => $data->orderStatus,
            "remark"    => $data->otherInfo
        ];

        $notice = $this->wxApp->notice;
        $notice->to($data->openId)
            ->uses($templateId);
        if($data->url){
            $notice->andUrl($data->url);
        }
        return $notice->data($info)->send();


    }


    public function send_user_register_template(UserRegisterTemplateModel $userRegisterTemplateModel)
    {

        $data   = $userRegisterTemplateModel;
        if($this->sendTemplate == false) return;
        $templateId = "IZXVmcfklzJCa0Q-HyuLpTEqjyQDWdl08MV2K568gYo";
        $info       = [
            "first"     => $data->title,
            "keyword1"  => $data->name,
            "keyword2"  => $data->mobile,
            "remark"    => $data->detail
        ];

        $notice = $this->wxApp->notice;
        $notice->to($data->openId)
            ->uses($templateId);
        if($data->url){
            $notice->andUrl($data->url);
        }
        return $notice->data($info)->send();
    }

    /**
     * 获得微信支付数据
     * @param string $body 订单说明
     * @param string $detail 订单详情
     * @param float $money  订单金额
     * @param string $orderNumber 订单编号
     * @param string $callbackUrl 微信回调
     * @param string $openId 微信openId
     * @return string
     * */
    public function get_wx_pay_config($openId,$money,$orderNumber,$body,$detail,$callbackUrl)
    {
        $app        = $this->get_weixin_app();
        $payment    = $app->payment;
        $attributes = [
            'trade_type'       => 'JSAPI', // JSAPI，NATIVE，APP...
            'body'             => $body,
            'detail'           => $detail,
            'out_trade_no'     => $orderNumber,
            'total_fee'        => $money * 100, // 单位：分
            'notify_url'       => $callbackUrl, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'openid'           => $openId, // trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识，
            'attach'           => "ui=10"
        ];




        $order  = new Order($attributes);
        $result = $payment->prepare($order);
        if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS')
        {
            $prepayId   = $result->prepay_id;
            //$json       = $payment->configForJSSDKPayment($prepayId);
            $json        = $payment->configForPayment($prepayId);

            return $json;
        }
        return false;
    }

    /**
     * 获得miniapp实例
     * */
    public function miniApp(){
        //根据code来获取微信的openId
        $miniConfig     = config("wx.mini");

        $options = [
            'mini_program' => [
                'app_id'   => $miniConfig["appId"],
                'secret'   => $miniConfig["appSecret"],
            ],
            'app_id'   => $miniConfig["appId"],
            'secret'   => $miniConfig["appSecret"],
            "payment"  => [
                "merchant_id"   => $miniConfig['matchId'],
                "key"           => $miniConfig["matchKey"],
            ]
        ];

        return new Application($options);
    }

    /**
     * 获得小程序支付配置
     * @param $openId string openId
     * @param $money float 支付金额
     * @param $orderNumber string 订单编号
     * @param $body string 支付描述
     * @param $detail string 支付详细说明
     * @param $callbackUrl string 支付回调url
     * @return array
     *
     * */
    public function get_miniapp_pay_config($openId,$money,$orderNumber,$body,$detail,$callbackUrl){

        $miniApp    = $this->miniApp();
        $payment    = $miniApp->payment;

        $attributes = [
            'trade_type'       => 'JSAPI', // JSAPI，NATIVE，APP...
            'body'             => $body,
            'detail'           => $detail,
            'out_trade_no'     => $orderNumber,
            'total_fee'        => $money * 100, // 单位：分
            'notify_url'       => $callbackUrl, // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'openid'           => $openId, // trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识，
            'attach'           => "ui=10"
        ];

        $order  = new Order($attributes);
        $result = $payment->prepare($order);
        if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS')
        {
            $prepayId       = $result->prepay_id;
            //$json         = $payment->configForJSSDKPayment($prepayId);
            $config         = $payment->configForPayment($prepayId,false);
            $config['prepayId']     = $prepayId;
            $config['accessToken']  = $miniApp->access_token->getToken();
            return $config;
        }
        return false;
    }


    /**
     * 发送VIP服务购买成功通知
     * @param $openId string 用户的openId
     * @param $orderSn string 订单编号
     * @param $money float 订单金额
     * @param $content string 订单内容
     * @param $note string 备注
     */
    public function send_miniapp_buy_vip_success_msg($openId,$orderSn,$money,$content,$note,$prepayId)
    {
        $client     = new Curl();
        $templateId = "kCC2UXDmt3rTEQYjlKbbbNT-PPgSEvIUEutrjnJ1tbg";
        $token      = $this->miniApp()->access_token->getToken();

        $info       = [
            "keyword1"  => ["value"=>$orderSn],
            "keyword2"  => ["value"=>$money],
            "keyword3"  => ["value"=>$content],
            "keyword4"  => ["value"=>$note]
        ];
        $url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=".$token;
        $params = [
            "touser"        => $openId,
            "template_id"   => $templateId,
            "page"          => "/pages/home/index/index",
            "form_id"       => $prepayId,
            "data"          => $info
        ];

        $res = $client->Post($url,$params,true);

        mylogger($res);
    }

    /**
     * 创建小程序二维码图片
     * @param $page string 页面路径
     * @param $scene string 场景值
     * @param $filepath string 图片存储路径
     * @param $info array 信息
     * @return boolean
     * */
    public function create_mini_qrcode_img($page,$scene,$filepath,$info=[]){

        $token  = $this->miniApp()->access_token->getToken();
        //$token  = "17_GGLRx-kZrPuzuMZRPIb6v6oQCbu80C-Evd-p9LmUngZSujiObsGDFxqFo-LiupmT6MmOwRboBdCo-mbg7hCWRUco1KSsXgLqOkJIQWbkTqNkOEQQGj1KntiEosIxfpx3k6UTVnwh51Rlvgw3QKNdADAKEH";
        $url    = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$token;
        $params = ['page'=>$page,'scene'=>$scene];
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => false,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS =>\GuzzleHttp\json_encode($params),
            CURLOPT_HTTPHEADER => array(
                "Content-Type: application/json"
            ),
        ));

        $response   = curl_exec($curl);
        $err        = curl_error($curl);

        curl_close($curl);

        if ($err) {

            return false;

        } else {

            file_put_contents($filepath,$response);
        }
    }
}


